package com.Chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

// 客户端处理线程
class ClientHandler implements Runnable {
    private Socket socket;// Socket接口
    private String clientId;// 客户端ID
    private BufferedReader reader;// 输入流；BufferedReader可以通过readLine()方法读取一行数据
    private PrintWriter writer;// 输出流,PrintWriter和System.out.println()差不多都提供类似的方法，但PrintWriter功能更强大专用与文本流的输出
    private boolean isLoggedIn = false;

    public ClientHandler(Socket socket, String clientId) {// 构造函数
        this.socket = socket;//接收服务器端传入的socket接口
        this.clientId = clientId;//接收服务端传入的clientId
        try {
            //getInputStream字符流通过InputStreamReader将字节流转换为字符流
            this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取socket接口上的输入流
            this.writer = new PrintWriter(socket.getOutputStream(), true);//获取socket接口上的输出流
        } catch (IOException e) {
            System.err.println("客户端处理程序初始化错误: " + e.getMessage());
        }
    }

    @Override
    public void run() {// 线程运行方法
        try {
            writer.println("欢迎 " + clientId + "! 连接到聊天服务器");
            writer.println("请先使用 /login 用户名 密码 登录，或使用 /register 用户名 密码 注册");

            String message;
            /*检查是否收到来自客户端的信息，并根据格式来处理*/
            while ((message = reader.readLine()) != null) {
                System.out.println("收到来自 " + clientId + " 的消息: " + message);

                // 处理特殊命令
                if (message.startsWith("/sendto ")) {
                    if (!isLoggedIn) {
                        writer.println("系统提示: 请先登录才能发送消息");
                        continue;
                    }
                    handleSendToCommand(message);//将信息发送给指定客户端
                } else if (message.equals("/list")) {
                    sendClientList();// 发送在线客户端列表
                } else if (message.equals("/help")) {
                    sendHelp();//让客户端知道如何使用
                } else if(message.startsWith("/register")){// 注册账号
                    String[] parts = message.split(" ", 3);
                    if (parts.length < 3) {
                        writer.println("注册格式错误，正确格式: /register 用户名 密码");
                    } else {
                        int result = MultiThreadedChatServer.registerUser(parts[1], parts[2]);
                        if(result == 1){
                            writer.println("注册成功！");
                        } else if(result == 2){
                            writer.println("用户已存在！");
                        } else {
                            writer.println("注册失败，请重试");
                        }
                    }
                } else if (message.startsWith("/login")) {//登录
                    if (isLoggedIn) {
                        writer.println("系统提示: 您已经登录了");
                        continue;
                    }
                    String[] parts = message.split(" ", 3);
                    if (parts.length < 3) {
                        writer.println("登录格式错误，正确格式: /login 用户名 密码");
                    } else {
                        int result = MultiThreadedChatServer.loginUser(parts[1], parts[2], this.clientId);
                        switch (result) {
                            case 0:
                                writer.println("登录成功！");
                                isLoggedIn = true;
                                break;
                            case 1:
                                writer.println("用户不存在！");
                                break;
                            case 2:
                                writer.println("密码错误！");
                                break;
                            case 3:
                                writer.println("系统错误，请稍后重试");
                                break;
                        }
                    }
                } else if (message.equals("/logout")) {
                    if (isLoggedIn) {
                        MultiThreadedChatServer.removeClient(clientId);
                        isLoggedIn = false;
                        writer.println("已退出登录");
                    } else {
                        writer.println("您尚未登录");
                    }
                } else if (message.startsWith("/broadcast ")) {
                    if (!isLoggedIn) {
                        writer.println("系统提示: 请先登录才能发送广播");
                        continue;
                    }
                    String broadcastMessage = message.substring(11);
                    MultiThreadedChatServer.broadcastMessage(broadcastMessage, this.clientId);
                    writer.println("广播已发送");
                } else {
                    writer.println("系统提示: 未知命令。输入 /help 查看帮助");//发送错误信息
                }
            }
        } catch (IOException e) {
            System.err.println("客户端 " + clientId + " 连接错误: " + e.getMessage());
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                System.err.println("关闭客户端连接错误: " + e.getMessage());
            }
            MultiThreadedChatServer.removeClient(clientId);//移除该客户端
        }
    }

    // 处理发送消息命令
    private void handleSendToCommand(String message) {
        try {
            // 命令格式: /sendto [目标用户名] [消息内容]
            String[] parts = message.split(" ", 3);//根据空格进行分割为3个部分
            if (parts.length != 3) {//数量不为3则返回错误信息
                writer.println("系统提示: 命令格式错误。正确格式: /sendto [用户名] [消息内容]");
                return;
            }

            String targetUsername = parts[1];//目标用户名
            String messageContent = parts[2];//消息内容

            // 查找目标用户对应的clientId
            String targetClientId = MultiThreadedChatServer.getClientIdByUsername(targetUsername);

            if (targetClientId == null) {
                writer.println("系统提示: 用户 " + targetUsername + " 不在线或不存在");
                return;
            }

            if (targetClientId.equals(this.clientId)) {
                writer.println("系统提示: 不能给自己发送消息");
                return;
            }

            MultiThreadedChatServer.sendMessageToClient(targetClientId, messageContent, this.clientId);
            writer.println("系统提示: 消息已发送给 " + targetUsername);

        } catch (Exception e) {
            writer.println("系统提示: 发送消息时发生错误: " + e.getMessage());
        }
    }

    // 发送客户端列表
    private void sendClientList() {
        StringBuilder list = new StringBuilder("在线用户列表:\n");
        for (String username : MultiThreadedChatServer.getOnlineUsernames()) {
            list.append("- ").append(username).append("\n");
        }
        if (MultiThreadedChatServer.getOnlineUsernames().isEmpty()) {
            list.append("暂无在线用户\n");
        }
        writer.println(list.toString());
    }

    // 发送帮助信息
    private void sendHelp() {
        String help = """
            ===== 聊天服务器帮助 =====
            /register [用户名] [密码] - 注册新账号
            /login [用户名] [密码] - 登录账号
            /logout - 退出登录
            /list - 查看在线用户列表
            /sendto [用户名] [消息] - 向指定用户发送私聊消息
            /broadcast [消息] - 向所有在线用户发送广播
            /help - 显示此帮助信息
            /quit - 退出客户端
            =========================
            """;
        writer.println(help);
    }

    // 发送消息给此客户端
    public void sendMessage(String message) {
        writer.println(message);
    }

    // 获取客户端ID
    public String getClientId() {
        return clientId;
    }
}